<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
        //vue2部分源码
export function observer(data){
    // 判断是否为对象
    if(typeof data != 'object' || data  == null){
        return data;//如果为object和null不需要劫持
    }
    // 对象通过class类进行劫持Observer观测数据对数据进行劫持
    return new Observer(data)
}
class Observer{
    constructor(value){
        this.walk(value)//为什么vue3使用proxy：因为proxy可以对所有对象进行监听劫持并且是懒加载
    }
    walk(data){
        let keys = Object.keys(data)//vue2中为了全部监听到将对象进行递归分割按顺序放入Object.defineProperty中以确保全部监听到
        for(let i = 0; i< keys.length; i++){
            // 对每个属性进行劫持
            let key = keys[i]
            let value = data[key]
            defineReactive(data,key,value)
        }
    }
}
// 对对象中的属性进行劫持
function defineReactive(data,key,value){
    Object.defineProperty(data,key,{
        get(){
            // 获取某个值触发
            console.log('获取')
            return value
        },
        set(newValue){
            // 修改时触发
            if(newValue == value) return;
            value = newValue
        },
    })
}

// vue2数据劫持采用Object.defineProperty  缺点：对象中的一个属性{a:1,b:2}只能对对象中的一个属性进行劫持
    </script>
  </body>
</html>
